package com.freestyle.jmssample.rabbitmq;

import com.freestyle.jmssample.api.SMSConstants;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.Connection;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.InitializingBean;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * Producer方的配置
 * Created by rocklee on 2022/1/6 11:24
 */
//@Configuration
@Deprecated
@Slf4j
public class AmqpProducerConfig implements InitializingBean {
  @Resource
  private RabbitTemplate amqpTemplate;
  @Resource
  private RabbitAdmin rabbitAdmin;

  //初始化
  private void init(){
    checkExchange(SMSConstants.SMS_EXCHANGE_DIRECT,BuiltinExchangeType.DIRECT,amqpTemplate);
  }
  public void bindQueue(String queue,String exChange,String routKey,RabbitTemplate rabbitTemplate){
    Connection connection=rabbitTemplate.getConnectionFactory().createConnection();
    Channel channel= connection.createChannel(false);
    try{
      //定义队列
      channel.queueDeclare(queue,false,false,false,null);
      //通道将队列与交换机、路由绑定
      channel.queueBind(queue,exChange,routKey);
    }
    catch (IOException e){
      e.printStackTrace();
    }
    finally {
      try {
        channel.close();
      } catch (IOException e) {
        e.printStackTrace();
      } catch (TimeoutException e) {
        e.printStackTrace();
      }
      connection.close();
    }
  }
  //检查是否存在交换机，不存在则创建
  public void checkExchange(String exChange,BuiltinExchangeType exchangeType,RabbitTemplate rabbitTemplate){
    Connection connection=rabbitTemplate.getConnectionFactory().createConnection();
    Channel channel= connection.createChannel(false);
    try{
      //用来检测相应的交换器是否存在。如果存在则正常返回:如果不存在则抛出异常: 404 channel exception ，同时Channel 也会被关闭
      try {
        channel.exchangeDeclarePassive(exChange);
      }
      catch (IOException e){
        channel=connection.createChannel(false);
        try {
          channel.exchangeDeclare(exChange, exchangeType);
        } catch (IOException ioException) {
          ioException.printStackTrace();
        }
      }
    }
    finally {
      try {
        channel.close();
      } catch (IOException e) {
        e.printStackTrace();
      } catch (TimeoutException e) {
        e.printStackTrace();
      }
      connection.close();
    }
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    // 生产者发送消息后，如果发送成功，则打印“消息发送成功”的日志信息
    amqpTemplate.setConfirmCallback((CorrelationData correlationData, boolean ack, String cause)->{
      log.info("消息发送成功:correlationData({}),ack({}),cause({})",correlationData,ack,cause);
    });
    // 生产者发送消息后，若发送失败，则输出“消息发送失败”的日志信息
    amqpTemplate.setReturnsCallback((ReturnedMessage message)->{
      log.info("消息丢失:exchange({}),route({}),replyCode({}),replyText({}),message:{}",message.getExchange(),message.getRoutingKey()
              ,message.getReplyCode(),message.getMessage());
    });
    init();
  }
}
